package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.dao.ClanDao;
import org.example.entity.*;
import org.example.exception.*;
import org.example.service.*;
import org.example.vo.FamilyVo;
import org.example.utils.TimeUtils;
import org.example.vo.FamilyTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.example.vo.ChildVo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.example.interceptor.LoginInterceptor.threadLocal;

@Service
public class ClanServiceImpl extends ServiceImpl<ClanDao, Clan> implements ClanService {
    @Autowired
    FamilyService familyService;
    @Autowired
    ClanService clanService;
    @Autowired
    UserService userService;
    @Autowired
    ClanDetailService clanDetailService;
    @Autowired
    FamilyDetailService familyDetailService;

    @Transactional
    @Override
    public void combineFamily(int sender,int receiver) throws  PermissionsDenyException{
        //这里翻转一下 现在其实是在receiver这里完成从sender到receiver的家族合并
        //引入了一个邀请函的东西，为了保证自己后面出错还能回顾，所以先不删除下面的combineFamily方法
        User cur = userService.getById(sender);
        int targetId = receiver;
        int targetPeople = getFamilyPeopleNum(targetId);
        int curPeople = getFamilyPeopleNum(cur.id);
        //TODO 人数限制还没做
        ClanDetail clanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits",1));
        Clan clan;
        if (clanDetail == null) {
//            第一次创建宗族
            clan = new Clan(TimeUtils.getCurrentTime());
            //取得人数
            clan.setHumanNum(targetPeople + curPeople);
            //创建族
            clanService.save(clan);
            //保存VIP家-族
            ClanDetail curClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, cur.id, cur.name, 1);
            clanDetailService.save(curClanDetail);

            //保存普通家长-族
            String name = userService.getById(targetId).getName();
            ClanDetail targetClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, targetId, name, 0);
            clanDetailService.save(targetClanDetail);
        } else {
            if (clanDetail.getRole() == 0) throw new PermissionsDenyException();
            //自己是已经有宗族的，且权限得是管理者
            clan = clanService.getOne(new QueryWrapper<Clan>().eq("id", clanDetail.getClanId()));
            String name = userService.getById(targetId).getName();
            ClanDetail targetClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, targetId, name, 0);
            clanDetailService.save(targetClanDetail);
        }
    }
    @Transactional
    @Override
    public void combineFamily(int targetId) throws PermissionsDenyException {
        User cur = threadLocal.get();
        int targetPeople = getFamilyPeopleNum(targetId);
        int curPeople = getFamilyPeopleNum(cur.id);
        ClanDetail clanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits",1));
        Clan clan;
        if (clanDetail == null) {
//            第一次创建宗族
            clan = new Clan(TimeUtils.getCurrentTime());
            //取得人数
            clan.setHumanNum(targetPeople + curPeople);
            //创建族
            clanService.save(clan);
            //保存VIP家-族
            ClanDetail curClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, cur.id, cur.name, 1);
            clanDetailService.save(curClanDetail);

            //保存普通家长-族
            String name = userService.getById(targetId).getName();
            ClanDetail targetClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, targetId, name, 0);
            clanDetailService.save(targetClanDetail);
        } else {
            if (clanDetail.getRole() == 0) throw new PermissionsDenyException();
            //自己是已经有宗族的，且权限得是管理者
            clan = clanService.getOne(new QueryWrapper<Clan>().eq("id", clanDetail.getClanId()));
            String name = userService.getById(targetId).getName();
            ClanDetail targetClanDetail = new ClanDetail(TimeUtils.getCurrentTime(), clan.id, targetId, name, 0);
            clanDetailService.save(targetClanDetail);
        }
    }

    public int getFamilyPeopleNum(int id) {
        int people = 0;
        FamilyDetail familyDetail = familyDetailService.getOne(new QueryWrapper<FamilyDetail>().eq("user_id", id));
        if (familyDetail == null) {
            people = 1;
        } else {
            Family family = familyService.getOne(new QueryWrapper<Family>().eq("id", familyDetail.getFamilyId()));
            people = family.getHumanNum();
        }
        return people;
    }
    //问题 批处理与单次处理
    @Override
    public FamilyTree findFamilyTree() throws NoClanException {
        User cur = threadLocal.get();
        ClanDetail clanDetailtmp = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits",1));
        if(clanDetailtmp==null) throw new NoClanException();

        List<ClanDetail> clanDetailList = clanDetailService.list(new QueryWrapper<ClanDetail>().eq("clan_id", clanDetailtmp.getClanId()).eq("exits",1));

        if (clanDetailList.size() == 0) throw new NoClanException();

        FamilyTree familyTree = new FamilyTree();
        familyTree.familyVoList = new ArrayList<>();
        for (ClanDetail clanDetail : clanDetailList
        ) {
            //管理者
            if(clanDetail.role==1) {
                familyTree.managerId = clanDetail.getUserId();
                familyTree.managerName=clanDetail.getName();
            }
            FamilyDetail familyDetailtmp = familyDetailService.getOne(new QueryWrapper<FamilyDetail>().eq("user_id", clanDetail.getUserId()));
            //如果未曾组建家庭
            if(familyDetailtmp==null) {
                FamilyVo familyVo = new FamilyVo(clanDetail.getName(),clanDetail.getClanId(),null);
                familyTree.familyVoList.add(familyVo);
                continue;
            }
            int familyId = familyDetailtmp.getFamilyId();

            List<FamilyDetail> familyDetails = familyDetailService.list(new QueryWrapper<FamilyDetail>().eq("family_id", familyId));

            ArrayList<ChildVo> childVoArrayList = new ArrayList<>();
            String parentName=clanDetail.getName(); int parentId=clanDetail.getUserId();
            for (FamilyDetail familyDetail : familyDetails
            ) {
                if (familyDetail.role == 0) {
                    ChildVo childVo = new ChildVo(familyDetail.name, familyDetail.userId);
                    childVoArrayList.add(childVo);
                } else {
                    parentName = familyDetail.name;
                    parentId = familyDetail.familyId;
                }
            }

            if(parentId==-1) continue;
            FamilyVo familyVo = new FamilyVo(parentName,parentId, childVoArrayList);
            familyTree.familyVoList.add(familyVo);
        }
        return familyTree;
    }

    /** 解散家族**/
    @Override
    public void disableClan() throws PermissionsDenyException, NoClanException {
        User cur = threadLocal.get();
        ClanDetail clanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits",1));
        if(clanDetail==null) throw new NoClanException();
        if(clanDetail.role==0) throw new PermissionsDenyException();
        int clanID = clanDetail.getClanId();
        List<ClanDetail> clanDetailList = clanDetailService.list(new QueryWrapper<ClanDetail>().eq("clan_id", clanID).eq("exits",1));
        Date currentTime = TimeUtils.getCurrentTime();
        for (int i = 0; i < clanDetailList.size(); i++) {
            clanDetailList.get(i).setUpdateTime(currentTime);
            clanDetailList.get(i).setExits(0);
        }
        clanDetailService.saveOrUpdateBatch(clanDetailList);

        Clan clan = clanService.getOne(new QueryWrapper<Clan>().eq("id", clanID).eq("exits", 1));
        clan.setExits(0);clan.setUpdateTime(TimeUtils.getCurrentTime());
        clanService.saveOrUpdate(clan);
    }

    @Override
    public void removeFamily(int targetId) throws PermissionsDenyException, NoClanException, NoInThisClan {
        User cur = threadLocal.get();
        //学生账号无法使用该功能
        if(cur.isChild==1) throw new PermissionsDenyException();
        ClanDetail clanDetail = clanDetailService.getOne(
                new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits",1));
        //自己都没在家族里
        if(clanDetail==null) throw new NoClanException();
        //权限不足
        if(clanDetail.getRole()==0) throw new PermissionsDenyException();

        //获取家族号
        int clanId = clanDetail.getClanId();
        clanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("clan_id",clanId).eq("user_id",targetId).eq("exits",1));
        if(clanDetail==null) throw new NoInThisClan();
        clanDetail.setExits(0);
        clanDetail.setUpdateTime(TimeUtils.getCurrentTime());
        clanDetailService.saveOrUpdate(clanDetail);

        int familyPeopleNum = getFamilyPeopleNum(targetId);
        Clan clan = clanService.getById(clanId);
        clan.humanNum-=familyPeopleNum;
        clan.setUpdateTime(TimeUtils.getCurrentTime());
        clanService.saveOrUpdate(clan);
    }

    @Override
    public void transferLeader(int targerId) throws PermissionsDenyException, NoInThisClan, ShouldNotBeStudent {
        User cur = threadLocal.get();
        //对方也不能是学生啊
        if(userService.getById(targerId).getIsChild()==1) throw new ShouldNotBeStudent();
        ClanDetail curClanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>().eq("user_id", cur.id).eq("exits", 1));
        if(curClanDetail.role==0) throw new PermissionsDenyException();

        //检查对方是否在族里
        ClanDetail targetClanDetail = clanDetailService.getOne(new QueryWrapper<ClanDetail>()
                .eq("clan_id",curClanDetail.getClanId()).eq("user_id",targerId));
        if(targetClanDetail==null) throw new NoInThisClan();
        targetClanDetail.setRole(1); targetClanDetail.setCreateTime(TimeUtils.getCurrentTime());
        curClanDetail.role=0; curClanDetail.setUpdateTime(TimeUtils.getCurrentTime());

        clanDetailService.saveOrUpdate(curClanDetail);
        clanDetailService.saveOrUpdate(targetClanDetail);
    }


}
